﻿using System;
using System.Threading;

namespace TestMutipleThreadRestEvent
{
    /// <summary>
    ///  封装ManualResetEvent，
    ///  NET4.0中可以通过 CountdownEvent 类解决
    /// </summary>
    public class MutipleThreadResetEvent : IDisposable
    {
        private readonly ManualResetEvent manualEvent = new ManualResetEvent(false);
        private readonly int total;
        private long current;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="total">需要等待执行的线程总数</param>
        public MutipleThreadResetEvent(int total)
        {
            this.total = total;
            current = total;
        }

        /// <summary>
        /// 唤醒一个等待的线程
        /// </summary>
        public void SetOne()
        {
            //到最后一个才发信号。
            // Interlocked 原子操作类 ,此处将计数器减1
            if (Interlocked.Decrement(ref current) == 0)
            {
                //当所有等待线程执行完毕时，唤醒等待的线程
                manualEvent.Set();
            }
        }

        /// <summary>
        /// 等待所以线程执行完毕
        /// </summary>
        public void WaitAll()
        {
            manualEvent.WaitOne();
        }

        /// <summary>
        /// 释放对象占用的空间
        /// </summary>
        public void Dispose()
        {
            ((IDisposable)manualEvent).Dispose();
        }
    }
}